\documentclass[12pt]{article}
\usepackage{amsmath,amsthm,amssymb}
\usepackage{times}
\usepackage{verbatim}

\newtheorem{defn}{Definition}
\newtheorem{lem}{Lemma}
\newtheorem{thm}{Theorem}

\begin{document}
\section*{Function Pointers}
\paragraph{}
In case you didn't know about these already, this is a function pointer:
\begin{verbatim}
int (*func) () f;
\end{verbatim}
\paragraph{}
This declares \verb=f= to be a pointer to a function returning an \verb=int=.
The compiler will turn
\begin{verbatim}
int f() {
  // ...
}
\end{verbatim}
\paragraph{}
into something like
\begin{verbatim}
.global f     # linker declaration

f:            # function definition
    ( ... )

f   ec4       # symbol table entry
\end{verbatim}
\paragraph{}
There is also a string table, as well as a global offset table. Without
function pointers, you will have to read these tables to find the addresses
for starting/resuming tasks. With them, you can conveniently ignore most
(all?) of these details.

\section*{Initializing Tasks}
\paragraph{}
To init a task, you will want to:
\begin{verbatim}
ldmia   {r4-fp,sp,lr}
movs    pc,lr
\end{verbatim}
\paragraph{}
The kernel stack pointer starts at \verb=1dffffc=. If we give the kernel
1 MB of memory, we can put task memory at \verb=1cffffc=. We can put a
specific function on the stack in C via
\begin{verbatim}
*(td->sp--) == /* first user task function address */
\end{verbatim}

\section*{GCC}
\paragraph{}
GCC uses the registers as follows:
\begin{itemize}
\item \verb=r0-r3=: scratch registers. These are NOT preserved across function
calls.
\item \verb=r4-r10=: persistent registers. These are preserved across function
calls; in particular, these should be preserved during your context switch.
\item \verb=r11=: frame pointer (fp).
\item \verb=r12=: index pointer (ip).
\item \verb=r13=: stack pointer (sp).
\item \verb=r14=: link register (lr).
\item \verb=r15=: program counter (pc).
\end{itemize}
\paragraph{}
You should look at the assembler generated by GCC for simple function calls.
It is roughly organized as follows:
\begin{verbatim}
mov ip, sp    # save previous stack pointer into ip
              # put the frame pointer at the top of saved registers
              # save the registers (but NOT sp, since this is changing)
              # create local vars (including arguments)
\end{verbatim}
\paragraph{}
When we leave a function, we have to load everything back again:
\begin{verbatim}
ldm sp, {r4-r10,fp,sp,...}
\end{verbatim}

\section*{And Now, A Random Trick}
When we exit the kernel, we execute \verb=movs pc,lr= just before the
\verb=entry= symbol, which must be placed into location \verb=0x28=. We can
achieve this in C by first declaring a couple of functions:
\begin{verbatim}
ker_exit() {

}
ker_entry() {

}
\end{verbatim}
\paragraph{}
This tricks the compiler into providing an address for the \verb=ker_entry()=
function that can be located by the linker; we can then place this address
into address \verb=0x28=.
\end{document}
